use model_graph_common::transport::http::http_get;
use std::{
    collections::HashMap,
    sync::{Arc, Mutex},
};
use url::Url;

use model_graph_types::{
    container::workflow::{
        HttpStatement, WorkflowBlockExecuteResult, WorkflowBlockExecuteResultBuilder,
        WorkflowBlockExecuteResultStatus, WorkflowErrorStrategy,
    },
    modeling::Value,
};

use crate::workflow::context::WorkflowContext;

pub async fn execute(
    statement: &HttpStatement,
    context: Arc<Mutex<WorkflowContext>>,
) -> anyhow::Result<WorkflowBlockExecuteResult> {
    let error_strategy = statement.error_strategy.clone();

    let result = _execute(statement, context).await;
    match result {
        Ok(v) => Ok(WorkflowBlockExecuteResultBuilder::default()
            .status(WorkflowBlockExecuteResultStatus::Succeeded)
            .source_handle("source")
            .result(v)
            .build()?),
        Err(err) => {
            if let Some(error_strategy) = error_strategy {
                match error_strategy {
                    WorkflowErrorStrategy::FailBranch => {
                        Ok(WorkflowBlockExecuteResultBuilder::default()
                            .status(WorkflowBlockExecuteResultStatus::Succeeded)
                            .source_handle("fail-branch")
                            .build()?)
                    }
                    _ => Ok(WorkflowBlockExecuteResultBuilder::default()
                        .status(WorkflowBlockExecuteResultStatus::Succeeded)
                        .source_handle("source")
                        .build()?),
                }
            } else {
                Ok(WorkflowBlockExecuteResultBuilder::default()
                    .status(WorkflowBlockExecuteResultStatus::Succeeded)
                    .source_handle("source")
                    .build()?)
            }
        }
    }
}

pub async fn _execute(
    statement: &HttpStatement,
    context: Arc<Mutex<WorkflowContext>>,
) -> anyhow::Result<HashMap<String, Value>> {
    //
    let url = &statement.url;
    //headers
    let headers = &statement.headers;
    //params
    let params = &statement.params;
    //填充parmas到url
    // 解析基础 URL
    let mut url = Url::parse(url).map_err(|err| anyhow::anyhow!("地址无效:{}", err))?;

    // 添加查询参数，自动编码
    url.query_pairs_mut()
        .extend_pairs(params.iter().map(|(k, v)| {
            //
            //
            (k, v)
        }));
    //
    tracing::debug!("http[{}]:{:?}", url, headers);
    let response_result = http_get(&url.to_string(), headers).await;

    match response_result {
        Ok((headers, body)) => {
            let mut outputs: HashMap<String, Value> = HashMap::new();
            tracing::debug!("{:?}", headers);
            if let Some(content_type) = headers.get(&String::from("content-type")) {
                //
                if content_type == &String::from("audio/wav") {
                } else {
                    outputs.insert(
                        String::from("body"),
                        Value::String(
                            String::from_utf8(body).map_err(|err| anyhow::anyhow!("{}", err))?,
                        ),
                    );
                }
            } else {
                outputs.insert(
                    String::from("body"),
                    Value::String(
                        String::from_utf8(body).map_err(|err| anyhow::anyhow!("{}", err))?,
                    ),
                );
            }
            Ok(outputs)
        }
        Err(err) => {
            tracing::error!("{}", err);
            Err(anyhow::anyhow!("{}", err))
        }
    }
}
